1. javapoet https://github.com/square/javapoet
开源java代码生成框架,提供Java Api生成.java源文件。
可以很方便的使用它根据注解、数据库模式、协议格式等来对应生成代码。
使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 private void generateHelloworld () throws IOException { MethodSpec main = MethodSpec.methodBuilder("main" ) .addModifiers(Modifier.PUBLIC,Modifier.STATIC) .addParameter(String[].class, "args" ) .addStatement("$T.out.println($S)" , System.class,"Hello World" ) .build(); TypeSpec typeSpec = TypeSpec.classBuilder("HelloWorld" ) .addModifiers(Modifier.FINAL,Modifier.PUBLIC) .addMethod(main) .build(); JavaFile javaFile = JavaFile.builder("com.example.helloworld" , typeSpec) .build(); javaFile.writeTo(System.out); } 作者:尸情化异 链接:https: 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
调用JavaPoet的API生成 1 2 3 4 5 6 7 package com.example.helloworld;public final class HelloWorld { public static void main (String[] args) { System.out.println("Hello, JavaPoet!" ); } }
2. RGen元模型生成器 Ruby Modelling and Generator Framework
Documentation 介绍
对象用来表示模型元素,类用来表示元模型元素。
RGen生成器模板
状态机生成器模板例子 它用来产生一个为每个复合状态创建的C++抽象类的头文件。跟随着状态模式和,能够从这个类得到每个子状态的状态类。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <% define 'Header ', :for => CompositeState do %> # (1) <% file abstractSubstateClassName +".h " do %> <% expand '/Util::IfdefHeader ', abstractSubstateClassName %> # (2) class <%= stateClassName %> ; <%nl% > class <%= abstractSubstateClassName %> # (3) { public:<%iinc% > # (4) <%=abstractSubstateClassName% > (<%=stateClassName% > &cont, char* name); virtual ~<%= abstractSubstateClassName %> () {}; <%nl% > <%= stateClassName %> &getContext() {<%iinc% > return fContext;<%idec% > } <%nl% > char *getName() { return fName; }; <%nl% > virtual void entryAction() {}; virtual void exitAction() {}; <%nl% > <% for t in (outgoingTransitions + allSubstateTransitions ).trigger %> # (5) virtual void <%= t %> () {}; <% end %> <%nl% > <%idec% > private:<%iinc% > char* fName; <%= stateClassName %> &fContext;<%idec% > }; <% expand '/Util::IfdefFooter ', abstractSubstateClassName %> <% end %> <% end %>
输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #ifndef ABSTRACTOPERATINGSUBSTATE_H_ #define ABSTRACTOPERATINGSUBSTATE_H_ class OperatingState ;class AbstractOperatingSubstate { public : AbstractOperatingSubstate(OperatingState &context, char * name); virtual ~AbstractOperatingSubstate() {}; OperatingState &getContext () { return fContext; } char *getName () { return fName; }; virtual void entryAction () {}; virtual void exitAction () {}; virtual void powerBut () {}; virtual void modeBut () {}; private : char * fName; OperatingState &fContext; }; #endif
3. Jet Model Robotization Jmr使用Jet模板生成代码。Jet是Eclipse开源的模板引擎
随着模型驱动开发(MDD)的发展而普及开来。Eclipse 项目有一个称为 JET 的技术项目就是一个专门的代码生成器。
参数 + 蓝图 = 所需的工件
使用 JET 在 Eclipse 中创建更多更好的代码
属性模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class <c:get select ="/app/@class" /> { <c:iterate select ="/app/property" var ="p" > private <c:get select ="$p/@type" /> <c:get select ="$p/@name" /> ; </c:iterate > public <c:get select ="/app/@class" /> () { <c:iterate select ="/app/property" var ="p" > this.<c:get select ="$p/@name" /> = <c:choose select ="$p/@type" > <c:when test ="'String'" > "<c:get select ="$p/@initial" /> "</c:when > <c:otherwise > <c:get select ="$p/@initial" /> </c:otherwise > </c:choose > ; </c:iterate > } <c:iterate select ="/app/property" var ="p" > public void set<c:get select =\ "camelCase ($p /@name )" /> (<c:get select ="$p/@type" /> <c:get select ="$p/@name" /> ) { System.out.println\ ("In set<c:get select =\ "camelCase ($p /@name )" /> ()"); this.<c:get select ="$p/@name" /> = <c:get select ="$p/@name" /> ; } public <c:get select =\ "$p /@type " /> get<c:get select ="camelCase($p/@name)" /> () { System.out.println("In get<c:get select ="camelCase($p/@name)" /> ()"); return <c:get select ="$p/@name" /> ; } </c:iterate > }
输入参数 1 2 3 4 5 <app class ="Car" > <property name ="model" type ="String" initial ="Honda Accord" /> <property name ="horsepower" type ="int" initial ="140" /> <property name ="spareTires" type ="boolean" initial ="true" /> </app >
生成的类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Car { private String model; private int horsepower; private boolean spareTires; public Car () { this .model = "Honda Accord" ; this .horsepower = 140 ; this .spareTires = true ; } public void setModel (String model) { System.out.println("In setModel()" ); this .model = model; } public String getModel () { System.out.println("In getModel()" ); return model; } public void setHorsepower (int horsepower) { System.out.println("In setHorsepower()" ); this .horsepower = horsepower; } public int getHorsepower () { System.out.println("In getHorsepower()" ); return horsepower; } public void setSparetires (boolean spareTires) { System.out.println("In setSparetires()" ); this .spareTires = spareTires; } public boolean getSparetires () { System.out.println("In getSparetires()" ); return spareTires; } }
4. AutoValue
“AutoValue is a great tool for eliminating the drudgery of writing mundane value classes in Java. It encapsulates much of the advice in Effective Java Chapter 2, and frees you to concentrate on the more interesting aspects of your program. The resulting program is likely to be shorter, clearer, and freer of bugs. Two thumbs up.”
AutoValue的是Google为了实现ValueClass设计的自动编译框架。
userguide
An Introduction to AutoValue
使用 1 2 3 dependencies { apt 'com.google.auto.value:auto-value:1.2' }
1 2 3 4 5 6 7 8 @AutoValue public abstract class Story { public abstract int id () ; public abstract String title () ; public static Story create (int id, String title) { new AutoValue_Story(id,title); } }
输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class Story { private int id; private String title; public Story (int id, String title) { this .id = id; this .title = title; } public int id () { return this .id; } public int title () { return this .title; } @Override public String toString () { return id + title; } @Override public int hashCode () { int hash = 7 ; hash = 31 * hash + this .id; hash = 31 * hash + (null == title ? 0 : title.hashCode()); return hash; } @Override public boolean equals (Object o) { if (this == o) return true ; if (o == null || !(o instanceof Stroy)) return false ; Story s = (Story) o; if (s.id != s.id) return false ; return s.title.equals(s.title); } }
5. Ruby 代码生成器 使用 Ruby 开发代码生成器
Class: ERB
ERB 是 Ruby 标准库的成员。
ERB 中使用<% %>
在模板文件中嵌入 Ruby 代码,<% %>
中的 Ruby 代码用于指定代码生成中数据模型相关的信息,模板中的文本给出了模型无关的信息。<% %>
中用于给出一段 Ruby 代码, <%= %>
表示表达式求值的结果将被输出出来。
ERB模板1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 /* * 项目名称:<%=projectName%> * * 创建日期 : <%=date%> * * 1.0 .0 版 (<%=bean.author%>) */ package com.<%=projectPackage%>.<%=bean.package%>.domain; <%if(bean.hasDateType())%>import java.util.Date;<%end%> public class <%=bean.domain%>Domain { <% bean.properties.each do |p|%> / ** <%=p.desc%> */ private <%=p.getJavaType()%> <%=p.field%>; <%end%> <% bean.properties.each do |p|%> / ** * 获取 <%=(p.desc)%> */ public <%=p.getJavaType()%> get<%=p.upcaseField()%>(){ return this.<%=p.field%>; } / ** * 设置 <%=(p.desc)%> */ public void set<%=p.upcaseField()%>(<%=p.getJavaType()%> <%=p.field%>){ this.<%=p.field%> = <%=p.field%>; } <%end%> }
使用 USER 数据模型作为输入,调用上述模板,得到的输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 package com.test.example.domain;public class UserDomain { private Integer id; private String name; private String idcard; private String address; public Integer getId () { return this .id; } public void setId (Integer id) { this .id = id; } public String getName () { return this .name; } public void setName (String name) { this .name = name; } public String getIdcard () { return this .idcard; } public void setIdcard (String idcard) { this .idcard = idcard; } public String getAddress () { return this .address; } public void setAddress (String address) { this .address = address; } }
6. CodeSmith 官网
CodeSmith 是一种基于模板的代码生成工具,它使用类似于 ASP.NET的语法来生成任意类型的代码或文本。
编写第一个代码模板
7. Velocity Velocity是一个基于Java的模板引擎。它允许任何人使用简单而强大的模板语言来引用Java代码中定义的对象。
Velocity的功能远远超出了网络的范围; 例如,它可以用于从模板生成SQL,PostScript和XML。它可以用作生成源代码和报告的独立实用程序,也可以用作其他系统的集成组件。例如,Velocity为各种Web框架提供模板服务,使他们能够根据真正的MVC模型,使视图引擎促进Web应用程序的开发。
User Guide
使用 Velocity 模板引擎快速生成代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class HelloVelocity { public static void main (String[] args) { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath" ); ve.setProperty("classpath.resource.loader.class" , ClasspathResourceLoader.class.getName()); ve.init(); Template t = ve.getTemplate("hellovelocity.vm" ); VelocityContext ctx = new VelocityContext(); ctx.put("name" , "velocity" ); ctx.put("date" , (new Date()).toString()); List temp = new ArrayList(); temp.add("1" ); temp.add("2" ); ctx.put("list" , temp); StringWriter sw = new StringWriter(); t.merge(ctx, sw); System.out.println(sw.toString()); } }
在 HelloVelocity 的代码中,首先 new 了一个 VelocityEngine 类,这个类设置了 Velocity 使用的一些配置,在初始化引擎之后就可以读取 hellovelocity.vm 这个模板生成的 Template 这个类。之后的 VelocityContext 类是配置 Velocity 模板读取的内容。这个 context 可以存入任意类型的对象或者变量,让 template 来读取。这个操作就像是在使用 JSP 开发时,往 request 里面放入 key-value,让 JSP 读取一样。
接下来就是写 hellovelocity.vm 文件了,这个文件实际定义了 Velocity 的输出内容和格式。1 2 3 4 5 6 7 8 //Hellovelocity.vm #set( $iAmVariable = "good!" ) Welcome $name to velocity.com today is $date. #foreach ($i in $list) $i #end $iAmVariable
输出1 2 3 4 5 Welcome velocity to velocity.com today is Sun Mar 23 19:19:04 CST 2014. 1 2 good!
8. StringTemplate http://www.stringtemplate.org/
模板 1 2 3 4 5 sqlTemplate(columns,condition) ::= <<select <columns;separator=","> from table where 1=1 <if(condition)>and <condition><endif> >>
JAVA调用 1 2 3 4 5 6 7 8 9 10 STGroup stg = new STGroupFile("dataExtractSql.stg" ); ST sqlST = stg.getInstanceOf("sqlTemplate" ); List<String> columnList = new LinkedList<String>(); columnList.add("order_id" ); columnList.add("price" ); columnList.add("phone" ); sqlST.add("columns" , columnList); sqlST.add("condition" , "dt='2017-04-04'" ); System.out.print(sqlST.render());
输出 1 2 3 select order_id,price,phonefrom table where 1 =1 and dt='2017-04-04'
9. FreeMarker
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
官网
http://try.freemarker.org/
10. mustache
mustache.java
语法